<?php

// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------
// 应用公共文件

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use think\Request;

if (!defined('__ROOT__')) {
	$_root = rtrim(dirname(rtrim($_SERVER['SCRIPT_NAME'], '/')), '/');
	define('__ROOT__', (('/' == $_root || '\\' == $_root) ? '' : $_root));
}

use \think\Db;
use \think\Loader;
use phpmailer\PHPMailer;
use app\common\model\User;
use think\Config;
use think\Validate;

// 应用公共文件

/**
 * @desc 接口数据返回格式
 * @param $data 数值 返回数据
 * @param $code Int  返回码
 * @param $message Sting 文字说明
 * @return json
 * @author lcx 2017/03/13
 */
function returnJson($code, $message = '', $data = '') {
	header('Content-Type:application/json; charset=utf-8');
	exit(json_encode(array('code' => $code, 'msg' => $message, 'data' => $data)));
}

/**
 *   后台接口数据返回格式
 * @param $code   返回码
 * @param string $message 文字说明
 * @param string $data  返回数据
 * @param string $count 总数据
 * @param string $allPage 总页数
 * @param string $nowPage 当前页数
 * @param $pageSize 每页条数
 * @author lcx 2017/03/13
 */
function returnJsonAdmin($code, $message = '', $data = '', $count = 0, $allPage = 0, $nowPage = 0, $pageSize = 1) {
	header('Content-Type:application/json; charset=utf-8');
	exit(json_encode(array('code' => $code, 'msg' => $message, 'data' => unsetnullKeyArr($data), 'count' => $count, 'allPage' => $allPage, 'nowPage' => $nowPage, 'pageSize' => $pageSize)));
}

/**
 * 记录按日期分组
 * @param type $arr 要进行分组的数组
 * @param type $filed //字段名称 create_time
 * @return type
 */
function groupVisit($arr, $filed) {
	if (empty($arr)) {
		return null;
	}
	$curyear = date('Y');
	$visit_list = [];
	foreach ($arr as $v) {
		if ($curyear == date('Y', $v[$filed])) {
			$date = date('m月d日', $v[$filed]);
		} else {
			$date = date('Y年m月d日', $v[$filed]);
		} $visit_list[$date][] = $v;
	} return $visit_list;
}

/**
 * 获取网站配置
 *
 * @param string $key
 * @param string $flag
 * @return mixed|\think\cache\Driver|boolean|unknown|NULL[]
 */
function getWebConfig($key = '', $flag = true) {

	$cache_key = 'web-config-' . json_encode($key);
	if (cache($cache_key) && $flag) {
		return cache($cache_key);
	}
	$c = Config::get('database');
	$sql = "SELECT * FROM " . $c['prefix'] . "config";
	if (is_array($key) && $key) {
		$sql .= " WHERE `name` in " . '(\'' . implode('\',\'', $key) . '\')';
	} else {
		$sql .= $key ? " WHERE `name`='$key'" : '';
	}

	$config_data = Db::name('config', array(), false)->query($sql);

	if ($key && !is_array($key)) {
		$temp = $config_data[0]['value'];
		cache($cache_key, $temp);
		return $temp;
	} else {
		$result = array();
		foreach ($config_data as $key => $val) {
			$result[$val['name']] = $val['value'];
		}
		cache($cache_key, $result);
		return $result;
	}
}

// 分析枚举类型配置值 格式 a:名称1,b:名称2
function parse_config_attr($string) {
	$array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
	if (strpos($string, ':')) {
		$value = array();
		foreach ($array as $val) {
			list($k, $v) = explode(':', $val);
			$value[$k] = $v;
		}
	} else {
		$value = $array;
	}
	return $value;
}

/**
 * 获取配置的分组
 * @param string $group 配置分组
 * @return string
 */
function get_config_group($group = 0) {
	$list = config('config_group_list');

	return $group ? $list[$group] : '';
}

/**
 * 获取配置的类型
 * @param string $type 配置类型
 * @return string
 */
function get_config_type($type = 0) {
	$list = config('config_type_list');
	return $list[$type];
}

/**
 * @desc   根据经纬度计算距离
 * @param  无
 * @date   2018-07-17
 * @author lcx
 * @param  [type]     $lat1 纬度1
 * @param  [type]     $lng1 经度1
 * @param  [type]     $lat2 纬度2
 * @param  [type]     $lng2 经度2
 * @return [type]           [description]
 */
function getDistance($lat1, $lng1, $lat2, $lng2) {
	if (empty($lat2) || empty($lng2) || empty($lat1) || empty($lng1)) {
		return 0;
	}
	$earthRadius = 6367000; //approximate radius of earth in meters
	$lat1 = ($lat1 * pi() ) / 180;
	$lng1 = ($lng1 * pi() ) / 180;
	$lat2 = ($lat2 * pi() ) / 180;
	$lng2 = ($lng2 * pi() ) / 180;

	$calcLongitude = $lng2 - $lng1;
	$calcLatitude = $lat2 - $lat1;
	$stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
	$stepTwo = 2 * asin(min(1, sqrt($stepOne)));
	$calculatedDistance = $earthRadius * $stepTwo;
	return round($calculatedDistance);
}

/**
 * 获取ip
 * @dateTime 2016-05-12T17:39:35+0800
 * @return   [type]                   [description]
 */
function inge_get_ip() {
	if (getenv('HTTP_CLIENT_IP')) {
		$ip = getenv('HTTP_CLIENT_IP');
	} else if (getenv('HTTP_X_FORWARDED_FOR')) {
		$ip = getenv('HTTP_X_FORWARDED_FOR');
	} else if (getenv('REMOTE_ADDR')) {
		$ip = getenv('REMOTE_ADDR');
	} else {
		$ip = $_SERVER['REMOTE_ADDR'];
	}
	return $ip;
}

/**
 * 获取浏览器
 */
function inge_get_browser() {
	$agent = $_SERVER["HTTP_USER_AGENT"];
	if (strpos($agent, 'MSIE') !== false || strpos($agent, 'rv:11.0')) { //ie11判断
		return "ie";
	} else if (strpos($agent, 'Firefox') !== false) {
		return "firefox";
	} else if (strpos($agent, 'Chrome') !== false) {
		return "chrome";
	} else if (strpos($agent, 'Opera') !== false) {
		return 'opera';
	} else if ((strpos($agent, 'Chrome') == false) && strpos($agent, 'Safari') !== false) {
		return 'safari';
	} else if (strpos($agent, 'MicroMessenger') !== false) {
		return 'weixin';
	} else {
		return 'unknown';
	}
}

/**
 * 获取浏览器版本号
 * @dateTime 2016-05-12T17:41:31+0800
 * @return   [type]                   [description]
 */
function inge_get_browser_ver() {
	if (empty($_SERVER['HTTP_USER_AGENT'])) {
		//当浏览器没有发送访问者的信息的时候
		return 'unknow';
	}
	$agent = $_SERVER['HTTP_USER_AGENT'];
	if (preg_match('/MSIE\s(\d+)\..*/i', $agent, $regs)) {
		return $regs[1];
	} elseif (preg_match('/FireFox\/(\d+)\..*/i', $agent, $regs)) {
		return $regs[1];
	} elseif (preg_match('/Opera[\s|\/](\d+)\..*/i', $agent, $regs)) {
		return $regs[1];
	} elseif (preg_match('/Chrome\/(\d+)\..*/i', $agent, $regs)) {
		return $regs[1];
	} elseif ((strpos($agent, 'Chrome') == false) && preg_match('/Safari\/(\d+)\..*$/i', $agent, $regs)) {
		return $regs[1];
	} else {
		return 'unknow';
	}
}

/**
 * 获取用户系统
 * @dateTime 2016-05-12T17:39:48+0800
 * @return   [type]                   [description]
 */
function inge_get_os() {
	$agent = $_SERVER['HTTP_USER_AGENT'];
	$os = false;
	// var_dump($agent);
	if (preg_match('/win/i', $agent) && strpos($agent, '95')) {
		$os = 'Windows 95';
	} else if (preg_match('/win 9x/i', $agent) && strpos($agent, '4.90')) {
		$os = 'Windows ME';
	} else if (preg_match('/win/i', $agent) && preg_match('/98/i', $agent)) {
		$os = 'Windows 98';
	} else if (preg_match('/win/i', $agent) && preg_match('/nt 6.0/i', $agent)) {
		$os = 'Windows Vista';
	} else if (preg_match('/win/i', $agent) && preg_match('/nt 6.1/i', $agent)) {
		$os = 'Windows 7';
	} else if (preg_match('/win/i', $agent) && preg_match('/nt 6.2/i', $agent)) {
		$os = 'Windows 8';
	} else if (preg_match('/win/i', $agent) && preg_match('/nt 10.0/i', $agent)) {
		$os = 'Windows 10';
		#添加win10判断
	} else if (preg_match('/win/i', $agent) && preg_match('/nt 5.1/i', $agent)) {
		$os = 'Windows XP';
	} else if (preg_match('/win/i', $agent) && preg_match('/nt 5/i', $agent)) {
		$os = 'Windows 2000';
	} else if (preg_match('/win/i', $agent) && preg_match('/nt/i', $agent)) {
		$os = 'Windows NT';
	} else if (preg_match('/win/i', $agent) && preg_match('/32/i', $agent)) {
		$os = 'Windows 32';
	} else if (preg_match('/linux/i', $agent)) {
		$os = 'Linux';
	} else if (preg_match('/unix/i', $agent)) {
		$os = 'Unix';
	} else if (preg_match('/sun/i', $agent) && preg_match('/os/i', $agent)) {
		$os = 'SunOS';
	} else if (preg_match('/ibm/i', $agent) && preg_match('/os/i', $agent)) {
		$os = 'IBM OS/2';
	} else if (preg_match('/Mac/i', $agent)) {
		$os = 'Mac OS';
	} else if (preg_match('/PowerPC/i', $agent)) {
		$os = 'PowerPC';
	} else if (preg_match('/AIX/i', $agent)) {
		$os = 'AIX';
	} else if (preg_match('/HPUX/i', $agent)) {
		$os = 'HPUX';
	} else if (preg_match('/NetBSD/i', $agent)) {
		$os = 'NetBSD';
	} else if (preg_match('/BSD/i', $agent)) {
		$os = 'BSD';
	} else if (preg_match('/OSF1/i', $agent)) {
		$os = 'OSF1';
	} else if (preg_match('/IRIX/i', $agent)) {
		$os = 'IRIX';
	} else if (preg_match('/FreeBSD/i', $agent)) {
		$os = 'FreeBSD';
	} else if (preg_match('/teleport/i', $agent)) {
		$os = 'teleport';
	} else if (preg_match('/flashget/i', $agent)) {
		$os = 'flashget';
	} else if (preg_match('/webzip/i', $agent)) {
		$os = 'webzip';
	} else if (preg_match('/offline/i', $agent)) {
		$os = 'offline';
	} else {
		$os = 'unknow';
	}
	return $os;
}

/**
 * 传入密码和随机数进行加密
 * @param $pwd 传入密码
 * @param $str  传入随机数
 * @return string 返回加密过后的密码
 */
function inge_encryption_pwd($pwd, $str) {
	$newStr = md5($pwd . $str);
	$newStr = substr($newStr, 6);
	$newStr = md5($newStr . $str);
	$newStr = crypt($newStr, $str);
	return $newStr;
}

/**
 * 获取随机字符
 * @param $len 需要的长度
 * @param type 为1 则大小写字母都可以  为0则为数字
 * @return string 返回获取到的随机字符串
 *
 */
function inge_get_random_str($len = 10, $type = '1') {
	$str = null;
	if ($type == '1') {
		$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
	} else {
		$strPol = "0123456789";
	}
	$max = strlen($strPol) - 1;
	for ($i = 0; $i < $len; $i++) {
		$str .= $strPol[rand(0, $max)];
	}
	return $str;
}

/**
 * 验证是否是手机号
 * @param $mobilephone
 * @return bool
 */
function inge_ismobile($mobilephone) {
	if (strlen($mobilephone) == 11) {
		if (preg_match("/^1[123456789]\d{9}$/", $mobilephone)) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

/**
 * 手机号隐藏
 */
function formatMobile($phone) {
	if (empty($phone)) {
		return "";
	}
	return substr($phone, 0, 3) . '****' . substr($phone, 7, 11);
}

/**
 * 验证是否为邮箱
 * @param  [type] $email [description]
 * @return [type]        [description]
 */
function inge_isemail($email) {
	$pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i";
//    if (preg_match("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+", $email)) {
	if (preg_match($pattern, $email)) {
		return true;
	} else {
		return false;
	}
}

/**
 * 二维数组根据某个字段排序
 * @param  [type] $arrUsers [description] 需要排序的数组
 * @param [type] $field     [description] 按哪个字段排序
 * @param [type] $way       [description] 排序顺序标志 SORT_DESC 降序；SORT_ASC 升序
 */
function inge_sortArrByField($arrUsers, $field, $way = 'SORT_ASC') {

	$sort = array(
		'direction' => $way,
		'field' => $field,
	);
	$arrSort = array();
	foreach ($arrUsers as $uniqid => $row) {
		foreach ($row as $key => $value) {
			$arrSort[$key][$uniqid] = $value;
		}
	}
	if ($sort['direction']) {
		array_multisort($arrSort[$sort['field']], constant($sort['direction']), $arrUsers);
	}

	return $arrUsers;
}

/**
 * 返回不含前缀的数据库表数组
 *
 * @author rainfer <81818832@qq.com>
 * @param bool
 * @return array
 */
function db_get_tables($prefix = false) {
	$db_prefix = config('database.prefix');
	$list = \think\Db::query('SHOW TABLE STATUS FROM ' . config('database.database'));
	$list = array_map('array_change_key_case', $list);
	$tables = array();
	foreach ($list as $k => $v) {
		if (empty($prefix)) {
			if (stripos($v['name'], strtolower(config('database.prefix'))) === 0) {
				$tables[] = strtolower(substr($v['name'], strlen($db_prefix)));
			}
		} else {
			$tables[] = strtolower($v['name']);
		}
	}
	return $tables;
}

/**
 * 递归重组节点信息为多维数组
 * @param array
 * @param int
 * @param string
 * @param string
 * @param string
 * @return array
 */
function node_merge(&$node, $pid = 0, $id_name = 'id', $pid_name = 'pid', $child_name = '_child') {
	$arr = array();
	foreach ($node as $v) {
		if ($v[$pid_name] == $pid) {
			$v[$child_name] = node_merge($node, $v[$id_name], $id_name, $pid_name, $child_name);
			$arr[] = $v;
		}
	}
	return $arr;
}

/**
 * 截取待html的文本
 * @author rainfer <81818832@qq.com>
 * @param string $html
 * @param int $max
 * @param string $suffix
 * @return string;
 */
function html_trim($html, $max, $suffix = '...') {
	$html = trim($html);
	if (strlen($html) <= $max) {
		return $html;
	}
	$non_paired_tags = array('br', 'hr', 'img', 'input', 'param'); // 非成对标签
	$html = preg_replace('/<img([^>]+)>/i', '', $html);
	$count = 0; // 有效字符计数(一个HTML实体字符算一个有效字符)
	$tag_status = 0; // (0:非标签, 1:标签开始, 2:标签名开始, 3:标签名结束)
	$nodes = array(); // 存放解析出的节点(文本节点:array(0, '文本内容', 'text', 0), 标签节点:array(1, 'tag', 'tag_name', '标签性质:0:非成对标签,1:成对标签的开始标签,2:闭合标签'))
	$segment = ''; // 文本片段
	$tag_name = ''; // 标签名
	for ($i = 0; $i < strlen($html); $i++) {
		$char = $html[$i]; // 当前字符
		$segment .= $char; // 保存文本片段
		if ($tag_status == 4) {
			$tag_status = 0;
		}
		if ($tag_status == 0 && $char == '<') {
			// 没有开启标签状态,设置标签开启状态
			$tag_status = 1;
		}
		if ($tag_status == 1 && $char != '<') {
			// 标签状态设置为开启后,用下一个字符来确定是一个标签的开始
			$tag_status = 2; //标签名开始
			$tag_name = ''; // 清空标签名
			// 确认标签开启,将标签之前保存的字符版本存为文本节点
			$nodes[] = array(0, substr($segment, 0, strlen($segment) - 2), 'text', 0);
			$segment = '<' . $char; // 重置片段,以标签开头
		}
		if ($tag_status == 2) {
			// 提取标签名
			if ($char == ' ' || $char == '>' || $char == "\t") {
				$tag_status = 3; // 标签名结束
			} else {
				$tag_name .= $char; // 增加标签名字符
			}
		}
		if ($tag_status == 3 && $char == '>') {
			$tag_status = 4; // 重置标签状态
			$tag_name = strtolower($tag_name);
			// 跳过成对标签的闭合标签
			$tag_type = 1;
			if (in_array($tag_name, $non_paired_tags)) {
				// 非成对标签
				$tag_type = 0;
			} elseif ($tag_name[0] == '/') {
				$tag_type = 2;
			}
			// 标签结束,保存标签节点
			$nodes[] = array(1, $segment, $tag_name, $tag_type);
			$segment = ''; // 清空片段
		}
		if ($tag_status == 0) {
			//echo $char.')'.$count."\n";
			if ($char == '&') {
				// 处理HTML实体,10个字符以内碰到';',则认为是一个HTML实体
				for ($e = 1; $e <= 10; $e++) {
					if ($html[$i + $e] == ';') {
						$segment .= substr($html, $i + 1, $e); // 保存实体
						$i += $e; // 跳过实体字符所占长度
						break;
					}
				}
			} else {
				// 非标签情况下检查有效文本
				$char_code = ord($char); // 字符编码
				if ($char_code >= 224) { // 三字节字符
					$segment .= $html[$i + 1] . $html[$i + 2]; // 保存字符
					$i += 2; // 跳过下2个字符的长度
				} elseif ($char_code >= 129) { // 双字节字符
					$segment .= $html[$i + 1];
					$i += 1; // 跳过下一个字符的长度
				}
			}
			$count++;
			if ($count == $max) {
				$nodes[] = array(0, $segment . $suffix, 'text', 0);
				break;
			}
		}
	}
	$html = '';
	$tag_open_stack = array(); // 成对标签的开始标签栈
	for ($i = 0; $i < count($nodes); $i++) {
		$node = $nodes[$i];
		if ($node[3] == 1) {
			array_push($tag_open_stack, $node[2]); // 开始标签入栈
		} elseif ($node[3] == 2) {
			array_pop($tag_open_stack); // 碰到一个结束标签,出栈一个开始标签
		}
		$html .= $node[1];
	}
	while ($tag_name = array_pop($tag_open_stack)) { // 用剩下的未出栈的开始标签补齐未闭合的成对标签
		$html .= '</' . $tag_name . '>';
	}
	return $html;
}

/**
 * 货币转换
 * @param float
 * @return string
 */
function long_currency($long) {
	return sprintf('%d.%02d', intval($long / 100), intval($long % 100));
}

/**
 * 货币转换
 * @param string
 * @return float
 */
function currency_long($currency) {
	$s = explode('.', trim($currency));
	switch (count($s)) {
		case 1:
			return $s[0] * 100;
		case 2:
			if (strlen($s[1]) == 1) {
				$s[1] .= '0';
			} else if (strlen($s[1]) > 2) {
				$s[1] = substr($s[1], 0, 2);
			}
			return $s[0] * 100 + $s[1];
	}
	return 0;
}

/**
 * 设置全局配置到文件
 *
 * @param $key
 * @param $value
 * @return boolean
 */
function sys_config_setbykey($key, $value) {
	$file = ROOT_PATH . 'data/conf/config.php';
	$cfg = array();
	if (file_exists($file)) {
		$cfg = include $file;
	}
	$item = explode('.', $key);
	switch (count($item)) {
		case 1:
			$cfg[$item[0]] = $value;
			break;
		case 2:
			$cfg[$item[0]][$item[1]] = $value;
			break;
	}
	return file_put_contents($file, "<?php\nreturn " . var_export($cfg, true) . ";");
}

/**
 * 设置全局配置到文件
 *
 * @param array
 * @return boolean
 */
function sys_config_setbyarr($data) {
	$file = ROOT_PATH . 'data/conf/config.php';
	if (file_exists($file)) {
		$configs = include $file;
	} else {
		$configs = array();
	}
	$configs = array_merge($configs, $data);
	return file_put_contents($file, "<?php\treturn " . var_export($configs, true) . ";");
}

/**
 * 获取全局配置
 *
 * @param $key
 * @return array|null
 */
function sys_config_get($key) {
	$file = ROOT_PATH . 'data/conf/config.php';
	$cfg = array();
	if (file_exists($file)) {
		$cfg = (include $file);
	}
	return isset($cfg[$key]) ? $cfg[$key] : null;
}

/**
 * 列出本地目录的文件
 * @author rainfer <81818832@qq.com>
 * @param string $path
 * @param string $pattern
 * @return array
 */
function list_file($path, $pattern = '*') {
	if (strpos($pattern, '|') !== false) {
		$patterns = explode('|', $pattern);
	} else {
		$patterns[0] = $pattern;
	}
	$i = 0;
	$dir = array();
	if (is_dir($path)) {
		$path = rtrim($path, '/') . '/';
	}
	foreach ($patterns as $pattern) {
		$list = glob($path . $pattern);
		if ($list !== false) {
			foreach ($list as $file) {
				$dir[$i]['filename'] = basename($file);
				$dir[$i]['path'] = dirname($file);
				$dir[$i]['pathname'] = realpath($file);
				$dir[$i]['owner'] = fileowner($file);
				$dir[$i]['perms'] = substr(base_convert(fileperms($file), 10, 8), -4);
				$dir[$i]['atime'] = fileatime($file);
				$dir[$i]['ctime'] = filectime($file);
				$dir[$i]['mtime'] = filemtime($file);
				$dir[$i]['size'] = filesize($file);
				$dir[$i]['type'] = filetype($file);
				$dir[$i]['ext'] = is_file($file) ? strtolower(substr(strrchr(basename($file), '.'), 1)) : '';
				$dir[$i]['isDir'] = is_dir($file);
				$dir[$i]['isFile'] = is_file($file);
				$dir[$i]['isLink'] = is_link($file);
				$dir[$i]['isReadable'] = is_readable($file);
				$dir[$i]['isWritable'] = is_writable($file);
				$i++;
			}
		}
	}
	$cmp_func = create_function('$a,$b', '
        if( ($a["isDir"] && $b["isDir"]) || (!$a["isDir"] && !$b["isDir"]) ){
            return  $a["filename"]>$b["filename"]?1:-1;
        }else{
            if($a["isDir"]){
                return -1;
            }else if($b["isDir"]){
                return 1;
            }
            if($a["filename"]  ==  $b["filename"])  return  0;
            return  $a["filename"]>$b["filename"]?-1:1;
        }
        ');
	usort($dir, $cmp_func);
	return $dir;
}

/**
 * 删除文件夹
 * @author rainfer <81818832@qq.com>
 * @param string
 * @param int
 */
function remove_dir($dir, $time_thres = -1) {
	foreach (list_file($dir) as $f) {
		if ($f['isDir']) {
			remove_dir($f['pathname'] . '/');
		} else if ($f['isFile'] && $f['filename']) {
			if ($time_thres == -1 || $f['mtime'] < $time_thres) {
				@unlink($f['pathname']);
			}
		}
	}
}

/**
 * 通过用户id获取用户名
 */
function get_username_byid($id) {
	$res = Db::table('__USER__')->where('user_id', $id)->find();
	if ($res) {
		return $res['user_name'];
	} else {
		return '';
	}
}

/**
 * 通用列表排序函数
 * @param  string $value [description]
 * @return [type]        [description]
 */
function listorder($idtitle, $id, $order, $modelobject) {
	foreach ($id as $key => $value) {
		$list[] = [$idtitle => $value, 'listorder' => $order[$key]];
	}
	$res = $modelobject->saveAll($list);
	return $res;
}

/**
 * 根据ID获取Term信息 传入$field参数，获取指定字段
 * @param  [type] $id   [description]
 * @param  string $field [description]
 * @return [type]       [description]
 */
function get_terminfo_by_newid($id, $field = '') {
	$res = Loader::model('Terms')->getTermForObjectId($id);
	if ($res) {
		$res = Loader::model('Terms')->where('term_id', $res['term_id'])->find();
		if ($res) {
			if ($field == '') {
				return $res;
			} else {
				return $res[$field];
			}
		}
	}
	return '';
}

function numinput_to_num($str) {
	return $string = str_replace(',', '', $str);
}

/**
 * 传入用户id获取等级信息
 * @param  [type] $uid [description]
 * @return [type]      [description]
 */
function store_get_level_by_uid($uid) {
	$map['user_id'] = $uid;
	$level_id = Db::table('__USER__')->where($map)->value('level');
	$level_data = Db::table('__USER_LEVEL__')->where('level_id', $level_id)->find();
	if (count($level_data)) {
		return $level_data;
	} else {
		return 0;
	}
}

/**
 * 传入用户id和amount获取等级
 * @param  [type] $uid    [description]
 * @param  [type] $amount [description]
 * @return [type]         [description]
 */
function store_get_level($uid, $amount) {
	$map['user_id'] = $uid;
	$level_id = Db::table('__USER__')->where($map)->value('level');
	$level_name = Db::table('__USER_LEVEL__')->where('level_id', $level_id)->find();
	if ($level_name) {
		return $level_name;
	} else {
		return 0;
	}
}

/**
 * 提升用户总消费额
 * @return [type] [description]
 */
function user_inc_amount($uid, $amo) {
	$map['user_id'] = $uid;
	$res = Db::table('__USER__')->where($map)->setInc('total_amount', $amo);
	if ($res) {
		return 1;
	} else {
		return 0;
	}
}

/**
 * 降低用户总消费额
 * @return [type] [description]
 */
function user_dec_amount($uid, $amo) {
	$map['user_id'] = $uid;
	$res = Db::table('__USER__')->where($map)->setDec('total_amount', $amo);
	if ($res) {
		return 1;
	} else {
		return 0;
	}
}

/**
 * 获取option表指定配置
 * @date: 2017年3月31日 下午1:54:45
 * @author: 姚荣
 * @param: $name
 * @return:array
 * v1 无数据加载错误 修复：Thans
 */
function get_options($name) {
	$res = Db::table('__OPTIONS__')
			->where('option_name', $name . '_options')
			->column('option_value');
	if ($res) {
		return json_decode($res['0'], true);
	} else {
		return false;
	}
}

/**
 * 获取site指定配置
 * @date: 2017年3月31日 下午1:59:49
 * @author: 姚荣
 * @return:array
 */
function get_site_options() {
	return $res = get_options('site');
}

/**
 * 获取seo指定配置
 * @date: 2017年3月31日 下午1:59:49
 * @author: 姚荣
 * @return:array
 */
function get_seo_options() {
	return $res = get_options('seo');
}

/**
 * 获取seo指定配置
 * @date: 2017年3月31日 下午1:59:49
 * @author: 姚荣
 * @return:array
 */
function get_oss_options() {
	return $res = get_options('oss');
}

/**
 * 获取商品一级分类
 * @return [type] [description]
 */
function get_goods_firstcat() {
	return Loader::model('GoodsCategory')->getFirstCat();
}

/**
 * 生成订单号
 * @return string
 */
function shop_create_orderid($userinfo) {
	return date('YmdHis') . inge_get_random_str(6, 0) . $userinfo['m_id'];
}

/**
 * 调用系统的API接口方法（静态方法）
 * api('User/getName','id=5'); 调用公共模块的User接口的getName方法
 * api('Admin/User/getName','id=5');  调用Admin模块的User接口
 * @param  string  $name 格式 [模块名]/接口名/方法名
 * @param  array|string  $vars 参数
 */
function api($name, $vars = array()) {
	$array = explode('/', $name);
	$method = array_pop($array);
	$classname = array_pop($array);
	$module = $array ? array_pop($array) : 'common';
	$callback = 'app\\' . $module . '\\Api\\' . $classname . 'Api::' . $method;
	dump($callback);
	exit;
	if (is_string($vars)) {
		parse_str($vars, $vars);
	}
	return call_user_func_array($callback, $vars);
}

//获取IP
function getIP() {
	if (getenv('HTTP_CLIENT_IP')) {
		$ip = getenv('HTTP_CLIENT_IP');
	} elseif (getenv('HTTP_X_FORWARDED_FOR')) {
		$ip = getenv('HTTP_X_FORWARDED_FOR');
	} elseif (getenv('HTTP_X_FORWARDED')) {
		$ip = getenv('HTTP_X_FORWARDED');
	} elseif (getenv('HTTP_FORWARDED_FOR')) {
		$ip = getenv('HTTP_FORWARDED_FOR');
	} elseif (getenv('HTTP_FORWARDED')) {
		$ip = getenv('HTTP_FORWARDED');
	} else {
		$ip = $_SERVER['REMOTE_ADDR'];
	}
	return $ip;
}

/**
 * 记录日志
 * @param  [type] $uid         [用户id]
 * @param  [type] $username    [用户名]
 * @param  [type] $description [描述]
 * @param  [type] $status      [状态]
 * @return [type]              [description]
 */
function writelog($uid, $username, $description, $status, $dbname) {
	$data['admin_id'] = $uid;
	$data['admin_name'] = $username;
	$data['description'] = $description;
	$data['status'] = $status;
	$data['ip'] = request()->ip();
	$data['add_time'] = time();
	$log = Db::name($dbname)->insert($data);
}

/**
 * 生成密码
 * @param  [type] $password      [密码]
 */
function setPassword($password) {
	if ($password) {
		$data = array();
		$chars = "0123456789";
		$str = "";
		for ($i = 0; $i < 8; $i ++) {
			$str .= substr($chars, mt_rand(1, strlen($chars) - 1), 1);
		}
		$data['strict'] = $str;
		$data['password'] = md5(md5($password) . $data['strict']);
		return $data;
	} else {
		return false;
	}
}

/**
 * 整理三级菜单树方法
 * @param $param
 * @return array
 */
function getTree($data, $pId = 0) {
	$tree = [];
	foreach ($data as $k => $v) {
		if ($v['pid'] == $pId) { //父亲找到儿子
			$v['child'] = getTree($data, $v['id']);
			$tree[] = $v;
			//unset($data[$k]);
		}
	}
	return $tree;
}

/**
 * 整理菜单树方法
 * @param $param
 * @return array
 */
function prepareMenu($param) {
	$parent = []; //父类
	$child = [];  //子类

	foreach ($param as $key => $vo) {

		if ($vo['pid'] == 0) {
			$vo['href'] = '#';
			$parent[] = $vo;
		} else {
			$vo['href'] = url($vo['url']); //跳转地址
			$child[] = $vo;
		}
	}

	foreach ($parent as $key => $vo) {
		foreach ($child as $k => $v) {

			if ($v['pid'] == $vo['id']) {
				$parent[$key]['child'][] = $v;
			}
		}
	}
	unset($child);
	return $parent;
}

/**  YSF
 *   时间戳转换
 *   2017年8月28日 下午14:10:00
 * @param $timestamp
 * @param int $type
 * @return false|string
 */
function get_time($timestamp, $type = 1) {
	if ($type == 1) {
		$time = date('Y-m-d H:i:s', $timestamp);
	} else {
		$time = date('Y-m-d', $timestamp);
	}
	return $time;
}

/**
 * 公共发送邮件函数
 * @author bg
 * @param $desc_content     邮件内容
 * @param $toemail          收件人邮箱
 * @param $title            邮箱标题
 * @return 0/1
 */
function sendEmail($desc_content, $toemail, $title) {
	$smtpConfig = config('smtp');
	if ($smtpConfig) {
		$mail = new PHPMailer();
		$mail->SMTPDebug = 0;
		$mail->isSMTP(); // 使用SMTP服务
		$mail->CharSet = "utf8"; // 编码格式为utf8，不设置编码的话，中文会出现乱码
		$mail->Host = $smtpConfig->MAIL_SMTP; // 发送方的SMTP服务器地址
		$mail->SMTPAuth = true; // 是否使用身份验证
		$mail->From = $smtpConfig->MAIL_ADDRESS;
		$mail->Username = $smtpConfig->MAIL_LOGINNAME; // 发送方的163邮箱用户名，就是你申请163的SMTP服务使用的163邮箱</span><span style="color:#333333;">
		$mail->Password = $smtpConfig->MAIL_PASSWORD; // 发送方的邮箱密码，注意用163邮箱这里填写的是“客户端授权密码”而不是邮箱的登录密码！</span><span style="color:#333333;">
		if (isset($smtpConfig->MAIL_SECURE)) {
			$mail->SMTPSecure = "ssl"; // 使用ssl协议方式</span><span style="color:#333333;">
		}
		$mail->Port = $smtpConfig->MAIL_PORT; // 163邮箱的ssl协议方式端口号是465/994
		$mail->setFrom("", "Mailer"); // 设置发件人信息，如邮件格式说明中的发件人，这里会显示为Mailer(xxxx@163.com），Mailer是当做名字显示
		$mail->addAddress($toemail, $toemail); // 设置收件人信息，如邮件格式说明中的收件人，这里会显示为Liang(yyyy@163.com)
		$mail->addReplyTo("", "Reply"); // 设置回复人信息，指的是收件人收到邮件后，如果要回复，回复邮件将发送到的邮箱地址
		//$mail->addCC("xxx@163.com");// 设置邮件抄送人，可以只写地址，上述的设置也可以只写地址(这个人也能收到邮件)
		//$mail->addBCC("xxx@163.com");// 设置秘密抄送人(这个人也能收到邮件)
		//$mail->addAttachment("bug0.jpg");// 添加附件
		$mail->Subject = $title; // 邮件标题
		$mail->Body = $desc_content; // 邮件正文
		//$mail->AltBody = "This is the plain text纯文本";// 这个是设置纯文本方式显示的正文内容，如果不支持Html方式，就会用到这个，基本无用
		if (!$mail->send()) {// 发送邮件
			return $mail->ErrorInfo;
		} else {
			return 1;
		}
	} else {
		return 0;
	}
}

/**
 * 公共发送短信函数
 * @author bg
 * @param $phone     手机号码
 * @param $content   内容
 * @return 0/1/-1;
 */
function sendSms($phone, $content) {
	$smsConfig = config('sms_account');
	if ($smsConfig) {
		$sms_config['uid'] = $smsConfig['uid'];
		$sms_config['content'] = $smsConfig['content'];
		$sms_config['passwd'] = $smsConfig['passwd'];
		$content = $content . "。【" . $sms_config['content'] . "】";
		$gateway = "http://sms.bamikeji.com:8890/mtPort/mt/normal/send?uid=" . $sms_config['uid'] . "&passwd=" . md5($sms_config['passwd']) . "&phonelist=" . $phone . "&content=" . $content;
		$result = file_get_contents($gateway);
		$ret = json_decode($result, true);
		if ($ret['success']) {
			return 1;
		} else {
			return 0;
		}
	} else {
		//不启用短信
		return -1;
	}
}

/**
 * Warning提示信息
 * @param string $type 提示类型 默认支持success, error, info
 * @param string $msg 提示信息
 * @param string $url 跳转的URL地址
 * @return void
 */
function alert($type = 'info', $msg = '', $url = '') {
	//多行URL地址支持
	$url = str_replace(array("\n", "\r"), '', $url);
	$alert = unserialize(stripslashes(cookie('alert')));
	if (!empty($msg)) {
		$alert[$type][] = $msg;
		cookie('alert', serialize($alert));
	}
	if (!empty($url)) {
		if (!headers_sent()) {
			// redirect
			header('Location: ' . $url);
			exit();
		} else {
			$str = "<meta http-equiv='Refresh' content='0;URL={$url}'>";
			exit($str);
		}
	}

	return $alert;
}

function parseAlert() {
	$alert = unserialize(stripslashes(cookie('alert')));
	cookie('alert', null);

	return $alert;
}

/**
 * 格式化字节大小
 * @param  number $size      字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 */
function format_bytes($size, $delimiter = '') {
	$units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
	for ($i = 0; $size >= 1024 && $i < 5; $i++) {
		$size /= 1024;
	}
	return $size . $delimiter . $units[$i];
}

/**
 * 菜单栏路由处理
 * @param unknown $string
 * @return boolean
 */
function UrlProcessing($string) {
	if (empty($string)) {
		return false;
	} else {
		$string = strtolower($string);
		$string = str_replace('_', '', $string);
		return $string;
	}
}

/*
 * URL装数组
 */

function UrlTrans($url) {
	$urlArray = explode('/', $url);
	return strtolower($urlArray[1]);
}

/**
 * 字符串截取，支持中文和其他编码
 * @static
 * @access public
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true) {
	$slice = $str;
	if (function_exists("mb_substr"))
		if (mb_strlen($str) > 15) {
			$slice = mb_substr($str, $start, $length, $charset);
		} else {
			$suffix = false;
		} elseif (function_exists('iconv_substr')) {
		$slice = iconv_substr($str, $start, $length, $charset);
		if (false === $slice) {
			$slice = '';
		}
	} else {
		$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
		$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
		$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
		$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
		preg_match_all($re[$charset], $str, $match);
		$slice = join("", array_slice($match[0], $start, $length));
	}
	return $suffix ? $slice . '****' : $slice;
}

/*
 *  生成员工编号（6位）
 *  @author ligang
 *  @param int  $time
 *  @return int
 */

function EmployeeNumber() {
	$checkEmployeeNumber = Db::name('personnel_number')->max('personnel_number');
	if (!$checkEmployeeNumber) {
		$number = 100001;
		return $number;
	} else {
		return $checkEmployeeNumber + 1;
	}
}

/*
 * 身份证校验、并截取生日(15 or 18)
 * @ligang
 * @return  bool
 */

function checkIdCard($idCard) {
	$result = preg_match('/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X|x)$/', $idCard);
	if ($result) {
		return true;
	} else {
		return false;
	}
}

/*
 *  根据身份证获取生日
 *  @author ligang
 *  @return int
 */

function getBirthday($idCard) {
	if (strlen($idCard) == 15) {
		$birthday = substr($idCard, 4, 4) . "-" . substr($idCard, 8, 2) . "-" . substr($idCard, 10, 2);
	} else {
		$birthday = substr($idCard, 6, 4) . "-" . substr($idCard, 10, 2) . "-" . substr($idCard, 12, 2);
	}
	return strtotime($birthday);
}

/*
 *  随机生成设备编号
 *  @author ligang
 *  @return int
 */

function randEquipmentsNumber() {
	$str = '';
	for ($i = 1; $i <= 10; $i++) {
		$str .= mt_rand(0, 9);
	}
	$checkNumber = Db::name('contract_equipment')->where(['equipments_number' => $str])->find();
	if (!$checkNumber) {
		return $str;
	}
	randEquipmentsNumber();
}

/**
 * 密码比较方法,所有涉及密码比较的地方都用这个方法
 * @param string $password 要比较的密码
 * @param string $passwordInDb 数据库保存的已经加密过的密码
 * @return boolean 密码相同，返回true
 */
function cms_compare_password($password, $passwordInDb, $slat) {
	if ($passwordInDb !== md5(md5($password) . $slat)) {
		return false;
	}
	return true;
}

/**
 * 生成密码
 * @param string $password 要比较的密码
 * @param string $slat 数据库保存的已经加密过的密码
 * @return string 密码相同，返回string
 */
function compare_password($password, $slat) {
	return md5(md5($password) . $slat);
}

/**
 * curl get 请求
 * @param $url
 * @return mixed
 */
function cms_curl_get($url) {
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_FAILONERROR, true);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
	curl_setopt($ch, CURLOPT_AUTOREFERER, true);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_TIMEOUT, 5);
	$SSL = substr($url, 0, 8) == "https://" ? true : false;
	if ($SSL) {
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名
	}
	$content = curl_exec($ch);
	return $content;
}

/**
 * @param $url
 * @param $post_data
 * @return mixed
 *        使用curl发送post请求
 */
function post_request($url, $post_data) {
	// 使用post发送请求
	$curlObj = curl_init();
	curl_setopt($curlObj, CURLOPT_URL, $url);
	curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, 1);
	// post数据
	curl_setopt($curlObj, CURLOPT_POST, 1);
	// post的变量
	curl_setopt($curlObj, CURLOPT_POSTFIELDS, $post_data);
	$output = curl_exec($curlObj);
	// 发送完毕后 关闭curl资源
	curl_close($curlObj);
	// 返回获取的数据
	return $output;
}

/**
 * 生成用户 token
 * @param $userId
 * @param $deviceType
 * @return string 用户 token
 */
function cms_generate_user_token($userId, $deviceType) {
	$userTokenQuery = Db::name("user_token")
			->where('user_id', $userId)
			->where('device_type', $deviceType);
	$findUserToken = $userTokenQuery->find();
	$currentTime = time();
	$expireTime = $currentTime + 24 * 3600 * 180;
	$token = md5(uniqid()) . md5(uniqid());
	if (empty($findUserToken)) {
		Db::name("user_token")->insert([
			'token' => $token,
			'user_id' => $userId,
			'expire_time' => $expireTime,
			'create_time' => $currentTime,
			'device_type' => $deviceType
		]);
	} else {
		Db::name("user_token")
				->where('user_id', $userId)
				->where('device_type', $deviceType)
				->update([
					'token' => $token,
					'expire_time' => $expireTime,
					'create_time' => $currentTime
		]);
	}

	return $token;
}

/**
 * 传递参数 生成工单编号
 * @param string $head
 * @return string
 */
function pay_sn($head) {
//    $order_number = strtoupper($head . dechex(date('m'))) . date('d') . substr(time(), - 5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
//    $checkWorkOrderNumber = Db::name('work_order')->where(['order_number' => $order_number])->find();
//    // 有就继续生成
//    if ($checkWorkOrderNumber) {
//        pay_sn('CQW');
//    }
//    return $order_number;
	return $head . date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}

/**
 * @return int|mixed
 *    生成工单编号（10位）
 *      YSF debug
 */
function workOrderNumber() {
	$checkWorkOrderNumber = Db::name('work_order')->max('order_number');
	if (!$checkWorkOrderNumber) {
		$number = 1000000001;
		return $number;
	} else {
		return $checkWorkOrderNumber + 1;
	}
}

/**
 * 递归将key-value数组中所有 null 替换成 ''
 * @return arr
 * @author luo
 */
function unsetnullKeyArr($arr) {
	$narr = array();
	if (empty($arr) || !is_array($arr)) {
		return $arr;
	}
	foreach ($arr as $key => $val) {
		$data = $val;
		if (is_object($val)) {
			$data = $val->toArray();
		}
		if (is_array($data)) {
			foreach ($data as $k => $v) {
				if (is_array($v)) {
					$data[$k] = unsetnullKeyArr($v);
				} else {
					empty($v) ? $data[$k] = '--' : $data[$k] = $v;
				}
			}
		} else {
			$data = empty($data) ? '--' : $data;
		}
		$narr[] = $data;
	}
	return $narr;
}

/**
 * 递归将数组中所有 null 替换成 ''
 * @return arr
 * @author luo
 */
function unsetnullArr($arr) {
	$narr = array();
	while (list($key, $val) = each($arr)) {
		if (is_array($val)) {
			$val = unsetnullArr($val);
			count($val) == 0 || $narr[$key] = $val;
		} else {
			empty($val) ? $narr[$key] = '' : $narr[$key] = $val;
		}
	}
	return $narr;
}

//model select返回数组格式数据
function selectArray($array) {
	if (empty($array) || !count($array)) {
		return false;
	}
	foreach ($array as $value) {
		$datarray[] = $value->toArray();
	}
	return $datarray;
}

//model find返回数组格式数据
function findArray($array) {
	if (!empty($array)) {
		return $array->toArray();
	}
	return false;
}

/**
 * 递归将数组中所有 null  '' 删除
 * @return arr
 * @author luo
 */
function array_remove_empty($arr) {
	$narr = array();
	while (list($key, $val) = each($arr)) {
		if (is_array($val)) {
			$val = array_remove_empty($val);
			count($val) == 0 || $narr[$key] = $val;
		} else {
			if (trim($val) != "") {
				$narr[$key] = $val;
			}
		}
	}
	unset($arr);
	return $narr;
}

/**
 * 替换null
 * @author ligang
 * @param array $array  需要检查的数组(仅支持一维、二维数组)
 * @param string $str   null替换的字符串
 * @return array
 * @date 2018/6/15 15:30
 */
function replaceNull(array $array, string $str = '') {
	if (empty($array)) {
		return $array;
	}

	if (count($array) == count($array, 1)) {
		foreach ($array as $key => $value) {
			if (is_null($value)) {
				$array[$key] = $str;
			}
		}
	} else {
		foreach ($array as $key => $value) {
			foreach ($value as $k => $v) {
				if (is_null($v)) {
					$array[$key][$k] = $str;
				}
			}
		}
	}
	return $array;
}

/**
 * 判断URL是否已经包含协议
 * @param String $url
 */
function urlIsAll($url) {
	$str = "http://";
	$strs = "https://";
	if (strpos($url, $str) === false && strpos($url, $strs) === false) {
		return false;
	}
	return true;
}

/** 判断数值是否在一维数组内
 * @param $value
 * @param $arr
 * @return bool
 */
function isInArr($value, $arr) {
	if (!is_array($arr)) {
		return false;
	}
	if (in_array($value, $arr)) {
		return true;
	}
	return false;
}

/**
 * @desc   保留两位小数并且不四舍五入
 * @param  无
 * @date   2018-09-06
 * @author lcx
 * @param  [type]     $num [description]
 * @return [type]          [description]
 */
function sprintfNumber($num) {
	return sprintf("%.2f", substr(sprintf("%.3f", $num), 0, -2));
}

/**
 * @desc   对多维数组,多个字段进行排序
 *  $arr = sortArrByManyField($array1,'id',SORT_ASC,'name',SORT_ASC,'age',SORT_DESC);  print_r($arr);
 * @param  无
 * @date   2018-09-06
 * @author lcx
 * @return [type]     [description]
 */
function sortArrByManyField() {
	$args = func_get_args();
	if (empty($args)) {
		return null;
	}
	$arr = array_shift($args);

	if (!is_array($arr)) {
		throw new Exception("第一个参数不为数组");
	}
	foreach ($args as $key => $field) {
		if (is_string($field)) {
			$temp = array();
			foreach ($arr as $index => $val) {
				$temp[$index] = $val[$field];
			}
			$args[$key] = $temp;
		}
	}
	$args[] = &$arr; //引用值
	call_user_func_array('array_multisort', $args);
	return array_pop($args);
}

//二维数组分页
function arrPage($arr, $page, $indexinpage) {
	if (empty($page)) {
		$page = 1;
	}
	if (empty($indexinpage)) {
		$indexinpage = 5;
	}
	$newarr = array_slice($arr, ($page - 1) * $indexinpage, $indexinpage);
	return $newarr;
}

//二维数组查找某一个值，并返回
function searchArray($array, $key1, $value1, $key2 = "", $value2 = "") {
	$arr = array();
	foreach ($array as $keyp => $valuep) {
		if (empty($key2) || empty($value2)) {
			if ($valuep[$key1] == $value1) {
				array_push($arr, $valuep);
			}
		} else if (empty($key1) || empty($value1)) {
			if ($valuep[$key2] == $value2) {
				array_push($arr, $valuep);
			}
		} else {
			if ($valuep[$key1] == $value1 && $valuep[$key2] == $value2) {
				array_push($arr, $valuep);
			}
		}
	}
	return $arr;
}

/**  YSF
 *   处理钱的格式
 * @param $money    钱 单位分
 * @param int $unit  单位1 是元 2是分
 * @param int $point  小数点位数
 * @return float|int
 */
function formatMoney($money, $unit = 2, $point = 0) {
	if ($unit == 1) {
		$money = $money / 100;
	}
	if ($point == 0) {
		$money = (int) $money;
	} else {
		$money = number_format($money, $point);
//        if ($money > 0) {
//            $money = (float) $money;
//        }
	}
	return $money;
}

/**
 * 处理钱的格式 元转成分 ，分转成元
 * 元转分 formatMoney（$money,1）
 * 分转成元 formatMoney（$money,2)
 * @param int $money 钱
 * @param int $unit 单位1 是元 2是分
 * @param int $point 小数点位数
 */
function formatMoneys($money, $unit = 2, $point = 2) {
	if (empty($money)) {
		return 0;
	}
	if ($unit == 1) {//将元转成分
		$money = intval($money * 100);
	} else {
		$reg = '/^[0-9][0-9]*$/';
		$money = $money / 100; //将分转成元
		if ($point == 0 || preg_match($reg, $money)) {
			$money = (int) $money;
		} else {
			$money = sprintf('%.' . $point . 'f', $money);
		}
	}
	return $money;
}

// 价格元转分--start-------------------------------------------------------------------------
/**
 * 价格由元转分
 * @param $price 金额
 * @return int
 */
function ncPriceYuan2fen($price) {
	$price = (int) ncPriceCalculate(100, "*", ncPriceFormat($price));
	return $price;
}

/**
 * PHP精确计算  主要用于货币的计算用
 * @param $n1 第一个数
 * @param $symbol 计算符号 + - * / %
 * @param $n2 第二个数
 * @param string $scale  精度 默认为小数点后两位
 * @return  string
 */
function ncPriceCalculate($n1, $symbol, $n2, $scale = '2') {
	$res = "";
	switch ($symbol) {
		case "+"://加法
			$res = bcadd($n1, $n2, $scale);
			break;
		case "-"://减法
			$res = bcsub($n1, $n2, $scale);
			break;
		case "*"://乘法
			$res = bcmul($n1, $n2, $scale);
			break;
		case "/"://除法
			$res = bcdiv($n1, $n2, $scale);
			break;
		case "%"://求余、取模
			$res = bcmod($n1, $n2, $scale);
			break;
		default:
			$res = "";
			break;
	}
	return $res;
}

/**
 * 价格格式化
 * @param int	$price
 * @return string	$price_format
 */
function ncPriceFormat($price) {
	$price_format = number_format($price, 2, '.', '');
	return $price_format;
}

// 价格元转分--end-------------------------------------------------------------------------

/**
 *    毫升转升
 * @param $water_ml
 * @return float|int
 */
function mlturnl($water_ml) {
	return $water_ml / 1000;
}

/**
 * 生成券码  优惠券码以C开头 提货码以D开头 邀请好友以I开头
 * @param $code_length 券码长度
 * @param $prefix 前缀
 */
function generate_promotion_code($code_length = 6, $prefix = 'C') {
	$characters = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz";
	$code = "";
	for ($i = 0; $i < $code_length - 1; $i ++) {
		$code .= $characters[mt_rand(0, strlen($characters) - 1)];
	}
	$code = $prefix . $code;
	if ($prefix == 'C') {
		$coupon_num = Db::name('coupon')->where(['code' => $code])->count();
		if ($coupon_num > 0) {
			generate_promotion_code($code_length, $prefix);
		}
	} else if ($prefix == 'D') {
		$pickup_code = Db::name('order_pickup_code')->where(['pick_up_sn' => $code])->count();
		if ($pickup_code > 0) {
			generate_promotion_code($code_length, $prefix);
		}
	} else if ($prefix == 'A') {
		$pickup_code = Db::name('article_cate')->where(['cate_sn' => $code])->count();
		if ($pickup_code > 0) {
			generate_promotion_code($code_length, $prefix);
		}
	}
	//$code =microtime().$code;
	return $code;
}

/**
 * 验证数据
 *
 * @param  $data array 验证数据
 * @param  $rule array 规则
 * @param  $msg  array 提示消息
 */
function checkedParm($data, $rule, $msg = array()) {
	$validate = new Validate($rule, $msg);
	$result = $validate->check($data);
	if (!$result) {
		returnJson(-1001, $validate->getError());
	}
}

/**
 * @param $url    地址
 * @param $param  参数json格式
 * @param bool $post_file 是否文件上传
 * @return bool|mixed
 */
function http_post($url, $param = [], $post_file = false) {
	$oCurl = curl_init();
	if (stripos($url, "https://") !== FALSE) {
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); // CURL_SSLVERSION_TLSv1
	}
	if (is_string($param) || $post_file) {
		$strPOST = $param;
	} else {
		$aPOST = array();
		foreach ($param as $key => $val) {
			$aPOST[] = $key . "=" . urlencode($val);
		}
		$strPOST = join("&", $aPOST);
	}
	curl_setopt($oCurl, CURLOPT_URL, $url);
	curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($oCurl, CURLOPT_POST, true);
	curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
	$sContent = curl_exec($oCurl);
	$aStatus = curl_getinfo($oCurl);
	curl_close($oCurl);
	if (intval($aStatus["http_code"]) == 200) {
		return json_decode($sContent, true);
	} else {
		return false;
	}
}

/**
 * 公共导出方法
 * @author ligang
 * @param array $tableTile      表头
 * @param array $field          字段名称，与表头对应
 * @param string $sheet_title   sheet名称
 * @param string $title         内容标题
 * @param array $data           导出数据
 * @param string $file_name     文件名
 * @param string $file_path     文件储存路径
 * @param string $suffix        文件后缀
 * @param bool $output          是否输出
 * @return string
 * @throws \PhpOffice\PhpSpreadsheet\Exception
 * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
 * @throws \think\Exception
 * @date 2018/11/26 14:56
 */
function export(array $tableTile, array $field, string $sheet_title, string $title, array $data, string $file_name, string $file_path, string $suffix = 'xlsx', bool $output = false) {
	$filename = $file_name . '.' . strtolower($suffix);
	switch (strtolower($suffix)) {
		case 'xlsx':
			$writerType = 'Xlsx';
			break;
		case 'xls':
			$writerType = 'Xls';
			break;
		case 'ods':
			$writerType = 'Ods';
			break;
		case 'csv':
			$writerType = 'Csv';
			break;
		case 'html':
			$writerType = 'Html';
			break;
		case 'tcpdf':
			$writerType = 'Tcpdf';
			break;
		case 'dompdf':
			$writerType = 'Dompdf';
			break;
		case 'mpdf':
			$writerType = 'Mpdf';
			break;
		default:
			throw new \think\Exception('文件格式不存在：' . $suffix, 500);
	}
	if (stripos($file_path, $filename) === false) {
		if (!file_exists($file_path)) {
			throw new \think\Exception('目录不存在：' . $file_path, 500);
		}
		$save_path = $file_path . $filename;
	} else {
		$save_path = $file_path;
	}
	$spreadsheet = new Spreadsheet();

	$spreadsheet->getProperties()
			->setCreator("Li Gang")
			->setLastModifiedBy("Li Gang")
			->setTitle("Excellent And Harmonious")
			->setSubject("You Jing Yun")
			->setDescription("You Jing Yun for Office 2007 XLSX, generated using PHP classes.")
			->setKeywords("office 2007 openxml php")
			->setCategory("You Jing Yun");

	//设置sheet名
	$spreadsheet->getActiveSheet()->setTitle($sheet_title);

	//设置表头
	$spreadsheet->getActiveSheet()->fromArray($tableTile, null, 'A2');

	$letter = 'A';
	for ($i = 0; $i < count($tableTile) - 1; $i++) {
		if ($letter == 'A') {
			$spreadsheet->getActiveSheet()->getColumnDimension($letter)->setWidth(22);
		}
		//操过Z后是从AA-AZ，BA-BZ,CA-CZ....
		$letter ++;
		if ($letter != 'A') {
			$spreadsheet->getActiveSheet()->getColumnDimension($letter)->setWidth(22);
		}
	}

	$titleStyleArray = [
		'font' => [
			'bold' => true,
			'size' => 14
		],
		'alignment' => [
			'horizontal' => Alignment::HORIZONTAL_CENTER,
			'vertical' => Alignment::VERTICAL_CENTER,
		],
	];
	//合并单元格，并设置标题和样式
	$spreadsheet->getActiveSheet()->mergeCells('A1:' . $letter . '1');
	$spreadsheet->getActiveSheet()->setCellValue('A1', $title);
	$spreadsheet->getActiveSheet()->getStyle('A1')->applyFromArray($titleStyleArray);

	//设置数据部分样式
	$dataStyleArray = [
		'alignment' => [
			'horizontal' => Alignment::HORIZONTAL_CENTER,
			'vertical' => Alignment::VERTICAL_CENTER,
		],
	];
	$spreadsheet->getActiveSheet()->getStyle('A2:' . $letter . (count($data) + 3))->applyFromArray($dataStyleArray);

	//设置行高(参数：pRow是表的行数，从一开始)
	$spreadsheet->getActiveSheet()->getRowDimension('1')->setRowHeight(50);

	//设置列宽
	//$spreadsheet->getActiveSheet()->getColumnDimension($letter)->setWidth(22);
	//设置默认列宽
	//$spreadsheet->getActiveSheet()->getColumnDimension($letter)->setAutoSize(true);

	$k = 3;
	foreach ($data as $key => $value) {
		$curr_letter = 'A';
		for ($j = 0; $j < count($tableTile); $j++) {
			$spreadsheet->getActiveSheet()->setCellValue($curr_letter . $k, $value[$field[$j]]);
			if ((is_numeric($value[$field[$j]]) || is_float($value[$field[$j]])) && $value[$field[$j]] < 9999) {
				//设置单元格格式
				$spreadsheet->getActiveSheet()->getStyle($curr_letter . $k)->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_NUMBER_00);
			}
//            elseif (strtotime($value[$field[$j]])){
//                $spreadsheet->getActiveSheet()->getStyle($curr_letter . $k)->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_YYYYMMDDSLASH);
//            }
			$curr_letter ++;
		}
		$k++;
	}

	if ($output) {
		header('Content-Type: application/vnd.ms-excel');
		header('Content-Disposition: attachment;filename="' . $filename . '"');
		header('Cache-Control: max-age=0');
		$writer = IOFactory::createWriter($spreadsheet, $writerType);
		$writer->save('php://output');
		exit();
	} else {
		$writer = IOFactory::createWriter($spreadsheet, $writerType);
		$writer->save($save_path);
		$request = Request::instance();
		return $request->domain() . '/' . $filename;
	}
}

/**
 * 路径拼接
 * @param String $url
 * @param int $type 1上传图片 2生成的二维码
 */
function UploadImgPath($url, $type = 1) {
	$way = config('pic_upload_way'); //1本地服务器上传 2七牛云上传
	if (empty($url)) {
		return "";
	}
	$str = "http://";
	$strs = "https://";
	if (strpos($url, $str) === false && strpos($url, $strs) === false) {
		if ($way == 2) {
			$url = config('qi_niu_url') . $url;
		} else {
			if ($type == 1) {
				$url = config('UPLOAD_PATH') . 'images/' . $url;
			} else {
				$url = WHOLE_HOST . 'qrcode/' . $url;
			}
		}
	}
	return $url;
}

/**
 *   生成合同编号
 * @param string $head
 * @return string
 */
function contract_no($head = 'CT') {
	$contract_no = $head . date('YmdHis') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 5);
	return $contract_no;
}

/*
 * 图片处理 base64转url 上传图片
 */

function convertBaseimg($base) {
	$date = date('Ymd') . '/';
	$img_path = './uploads/images/' . $date;
	file_exists($img_path) || mkdir($img_path, 0777);
	$img_file = uniqid() . mt_rand(100000, 999999) . '.jpg';
	// 图片数据
	$base = str_replace('data:image/png;base64,', '', $base);
	$base = str_replace('data:image/jpeg;base64,', '', $base);
	$base = str_replace('data:image/jpg;base64,', '', $base);
	$base = str_replace('data:image/gif;base64,', '', $base);
	$base = str_replace(' ', '+', $base);
	$data = base64_decode($base);

	// 保存图片
	$success = file_put_contents($img_path . $img_file, $data);
	// 图片路径
	// $url = "http://" . $_SERVER['HTTP_HOST'] . str_replace('index.php', '', $_SERVER['SCRIPT_NAME']) . substr($img_path, 2) . $img_file;
	$url = $date . $img_file;
	return $url;
}
